﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace AnaxibiaStudios.Smug.Internal
{
  public class Scope
  {
    public enum WrapTypeEnum
    {
      Brackets = 0,
      Parenthesis = 1,
      Angle = 2,
      Empty = 3,
      Quotes = 4,
      Square = 5,
      Comment = 6,
    };
    protected static string[][] _wrapSymbols;

    protected WrapTypeEnum WrapType { get; set; }
    protected string _text;

    static Scope()
    {
      _wrapSymbols = new string[][]
      {
          new string[]{"{","}"},
          new string[]{"(",")"},
          new string[]{"<",">"},
          new string[]{"",""},
          new string[]{"\"","\""},
          new string[]{"[","]"},
          new string[]{"\r\n/*","*/\r\n"},
      };
    }

    public Scope(WrapTypeEnum type)
    {
      _text = string.Empty;
      WrapType = type;
    }

    public Scope AddRange(IEnumerable<string> sources)
    {
      foreach (string source in sources)
        Add(source);

      return this;
    }

    public Scope Add(string str)
    {
      _text += str;
      return this;
    }

    public void Clear()
    {
      _text = string.Empty;
    }

    public static string Angle(params string[] strings)
    {
      return Wrap(WrapTypeEnum.Angle, strings);
    }
    public static string Parenthesis(params string[] strings)
    {
      return Wrap(WrapTypeEnum.Parenthesis, strings);
    }
    public static string Quote(params string[] strings)
    {
      return Wrap(WrapTypeEnum.Quotes, strings);
    }
    public static string Square(params string[] strings)
    {
      return Wrap(WrapTypeEnum.Square, strings);
    }
    public static string Brackets(params string[] strings)
    {
      return Wrap(WrapTypeEnum.Brackets, strings);
    }
    public static string Comment(string format, params string[] strings)
    {
      return Wrap(WrapTypeEnum.Comment, string.Format(format, strings.Select(str => ((object)(str ?? "[null]"))).ToArray()));
    }
    public static string Wrap(WrapTypeEnum type, params string[] strings)
    {
      var scope = new Scope(type);

      foreach (var str in strings)
      {
        scope.Add(str);
      }

      return scope.ToString();
    }

    public override string ToString()
    {
      int wrapTypeIndex = (int)WrapType;
      string open = _wrapSymbols[wrapTypeIndex][0];
      string close = _wrapSymbols[wrapTypeIndex][1];
      
      return open + _text + close;
    }

    public static Scope operator+ (Scope ths, string str)
    {
      return ths.Add(str);
    }
  }
}
